/**
 * Licensed under the Apache License Version 2.0.
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package net.interknit.knitter.fw;

import net.interknit.knitter.fw.hook.AuthenticationHook;
import net.interknit.knitter.fw.init.DefaultInitializer;
import net.interknit.knitter.fw.init.ServerInitializer;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;

/**
 *
 */
public class CmdLineServer implements Server
{
	private String host = "localhost";
	private int port = 9090;
	private boolean useSsl = false;

	private boolean useInInterceptor = true;
	private boolean useOutInterceptor = true;
	private boolean useInFaultInterceptor = true;
	private boolean useOutFaultInterceptor = true;

	public CmdLineServer(String[] cmdArgs)
	{
		for(int i = 0; cmdArgs != null && i < cmdArgs.length; i++)
		{
			if(cmdArgs[i].startsWith("-h"))
			{
				host = cmdArgs[i + 1];
			}
			else if(cmdArgs[i].startsWith("-p"))
			{
				port = new java.lang.Integer(cmdArgs[i + 1]).intValue();
			}
			else if(cmdArgs[i].startsWith("-ssl"))
			{
				useSsl = new java.lang.Boolean(cmdArgs[i + 1]).booleanValue();
			}
			else if(cmdArgs[i].startsWith("-login"))
			{
				useInInterceptor = new java.lang.Boolean(cmdArgs[i + 1]).booleanValue();
			}
			else if(cmdArgs[i].startsWith("-logout"))
			{
				useOutInterceptor = new java.lang.Boolean(cmdArgs[i + 1]).booleanValue();
			}
			else if(cmdArgs[i].startsWith("-logfaultin"))
			{
				useInFaultInterceptor = new java.lang.Boolean(cmdArgs[i + 1]).booleanValue();
			}
			else if(cmdArgs[i].startsWith("-logfaultout"))
			{
				useOutFaultInterceptor = new java.lang.Boolean(cmdArgs[i + 1]).booleanValue();
			}
		}
	}

	/**
	 * @return the host
	 */
	public String getHost()
	{
		return host;
	}

	/**
	 * @return the port
	 */
	public int getPort()
	{
		return port;
	}

	/**
	 * @return the useSsl
	 */
	public boolean useSsl()
	{
		return useSsl;
	}

	public void logIncoming(boolean useInInterceptor)
	{
		this.useInInterceptor = useInInterceptor;
	}
	public void logOutgoing(boolean useOutInterceptor)
	{
		this.useOutInterceptor = useOutInterceptor;
	}
	public void logIncomingFault(boolean useInFaultInterceptor)
	{
		this.useInFaultInterceptor = useInFaultInterceptor;
	}
	public void logOutgoingFault(boolean useOutFaultInterceptor)
	{
		this.useOutFaultInterceptor = useOutFaultInterceptor;
	}

	@Override
	public void serve(Class<? extends ServiceDelegate> serviceDelegateClass)
	{
		try
		{
			java.lang.String address =
				"http" + (useSsl ? "s" : "") + "://" + host + (port < 0 ? "" : (":" + port) + "/");

			org.apache.cxf.jaxrs.JAXRSServerFactoryBean sf =
				new org.apache.cxf.jaxrs.JAXRSServerFactoryBean();

			sf.getInInterceptors().add(new AuthenticationHook());

			if(useInInterceptor)
				sf.getInInterceptors().add(new LoggingInInterceptor());
			if(useOutInterceptor)
				sf.getOutInterceptors().add(new LoggingOutInterceptor());
			if(useInFaultInterceptor)
				sf.getInFaultInterceptors().add(new LoggingInInterceptor());
			if(useOutFaultInterceptor)
				sf.getOutFaultInterceptors().add(new LoggingOutInterceptor());

			ServiceDelegate serviceDelegate = serviceDelegateClass.newInstance();

			sf.setResourceClasses(serviceDelegateClass);
			sf.setResourceProvider(
					serviceDelegateClass,
					new org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider(serviceDelegate));

			sf.setAddress(address);

	    	String customInitalizer = CustomProperties.getCustomProperty(
	    			CustomProperties.SERVER_INITIALIZER_NAME);

	    	ServerInitializer initializer = null;

	    	try
	    	{
	    		initializer = (ServerInitializer)
	    				(Class.forName(customInitalizer).newInstance());
	    	}
	    	catch(Exception e)
	    	{
	    		initializer = new DefaultInitializer();
	    	}

	    	initializer.initialize(sf.getBus(), null, serviceDelegate);

			sf.create();

			System.out.println("Interknit: Server started at " + address);

			java.lang.Thread.sleep(Long.MAX_VALUE);

			System.out.println("Interknit: Server stopped.");

			System.exit(0);
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
	}
}
